import json

from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.utils import timezone
from django.views import View
from django_redis import get_redis_connection

from goods.models import GoodsCategory, SKU, SpecificationOption, GoodsVisitCount
from goods.utils import get_categories, get_hots


class ListView(View):
    def get(self, request, category_id, page_num):
        data = get_categories()

        breadcrumb = GoodsCategory.objects.get(id=category_id)

        sort = request.GET.get('sort')
        if sort == 'price':
            sort_key = '-price'
        elif sort == 'sales':
            sort_key = '-sales'
        else:
            sort = 'default'
            sort_key = '-create_time'

        skus = SKU.objects.filter(category_id=category_id).order_by(sort_key)
        pag = Paginator(skus, 5)
        current_page = pag.page(page_num)
        total_page = pag.num_pages
        current_skus = current_page.object_list

        context = {
            "categories": data,
            "breadcrumb": breadcrumb,
            "skus_page": current_skus,
            "current_page": page_num,
            "total_pages": total_page,
            "category": breadcrumb,
            "sort": sort
        }

        return render(request, 'list.html', context=context)


class HotView(View):
    def get(self, request, category_id):

        hot_skus = get_hots(category_id)

        res = {
            'code': 0,
            'errmsg': 'OK',
            'hot_skus': hot_skus
        }
        return JsonResponse(res)


class DetailView(View):
    def get(self, request, sku_id):
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return render(request, '404.html')

        # get all goods categories
        data = get_categories()

        # get category3
        breadcrumb = sku.category

        # get hot goods
        hot_skus = get_hots(sku.category_id)

        # get all specifications in current spu
        spu_specs = sku.spu.specs.all().order_by('id')

        # get all options of current sku
        sku_specs = sku.specs.all().order_by('id')
        sku_options = []
        for spec in sku_specs:
            sku_options.append(spec.option_id)

        # get goods specifications info
        specs = []
        for idx, spec in enumerate(spu_specs):
            spec_data = {'name': '', 'spec_options': []}
            specs.append(spec_data)

            spec_data['name'] = spec.name

            spec_options = spec.options.all()
            for option in spec_options:
                option_data = {'sku_id': None, 'value': option.value}
                spec_data['spec_options'].append(option_data)

                options = sku_options.copy()
                options[idx] = option.id

                skus = sku.spu.sku_set.all()
                for s in skus:
                    flag = True
                    for opt in options:
                        opt1 = SpecificationOption.objects.get(id=opt)
                        sps = opt1.skuspecification_set.all()
                        for sp in sps:
                            if sp.sku_id == s.id:
                                break
                        else:
                            flag = False

                        if not flag:
                            break

                    if flag:
                        option_data['sku_id'] = s.id

        context = {
            'categories': data,
            'breadcrumb': breadcrumb,
            'hot_skus': hot_skus,
            'sku': sku,
            'specs': specs,
        }
        return render(request, 'detail.html', context=context)


class DetailVisitView(View):
    def post(self, request, category_id):
        local_date = timezone.localdate()

        try:
            GoodsCategory.objects.get(id=category_id)
        except:
            return JsonResponse({'code': 9999, 'errmsg': 'category ID error'})

        try:
            visit_count = GoodsVisitCount.objects.get(category_id=category_id, date=local_date)
            visit_count.count += 1
            visit_count.save()

            res = {
                'code': 0,
                'errmsg': 'OK'
            }
            return JsonResponse(res)

        except:
            GoodsVisitCount.objects.create(category_id=category_id, date=local_date, count=1)

            res = {
                'code': 0,
                'errmsg': 'OK'
            }
            return JsonResponse(res)


class BrowseHistoryView(View):

    def get(self, request):
        user = request.user
        if not user.is_authenticated:
            return JsonResponse({'code': 9999, 'errmsg': 'user is not authenticated'})

        redis_client = get_redis_connection('history')
        histories = redis_client.lrange('history_%s' % user.id, 0, 5)
        history_skus = []
        for history in histories:
            sku = SKU.objects.get(id=history)
            sku_data = {'id': sku.id}
            history_skus.append(sku_data)

        res = {
            'code': 0,
            'errmsg': 'OK',
            'skus': history_skus
        }

        return JsonResponse(res)

    def post(self, request):

        user = request.user

        if not user.is_authenticated:
            return JsonResponse({'code': 9999, 'errmsg': 'user is not authenticated'})

        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')

        if not sku_id:
            return JsonResponse({'code': 9999, 'errmsg': 'error SKU ID'})

        redis_client = get_redis_connection('history')

        history_key = 'history_%s' % user.id
        redis_client.lrem(history_key, 0, sku_id)
        redis_client.lpush(history_key, sku_id)
        redis_client.ltrim(history_key, 0, 4)

        res = {
            'code': 0,
            'errmsg': 'OK'
        }

        return JsonResponse(res)
